package com.bwie.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bwie.mapper.RoleMapper;
import com.bwie.poi.StringUtils;
import com.bwie.pojo.Role;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.vo.LoginFrom;
import com.bwie.vo.LoginVo;
import com.bwie.vo.PageInfoVo;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.pojo.User;
import com.bwie.mapper.UserMapper;
import com.bwie.service.UserService;
import org.springframework.validation.annotation.Validated;

/**
 * @Author: 鑫仔
 * @Date: 2025/7/18 14:14
 * @Description:
 **/

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public R sendCode(String mobile) {

        boolean b = Validator.isMobile(mobile);
        if (!b) {
            return R.ERROR(500, "手机号格式不正确");
        }

        //是否唯一
        User userDb = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUserMobile, mobile));
        if (ObjectUtil.isNotEmpty(userDb)) {
            return R.ERROR(500, "手机号不可重复");
        }
        //生成验证码
        String code = RandomUtil.randomNumbers(4);

        //存入redis
        String mobileKey = mobile;
        redisTemplate.opsForValue().set(mobileKey, code, 5, TimeUnit.MINUTES);

        //发送验证码
        MobileMessageUtil.sendMobileMessage(mobile, code);
        return R.OK();
    }

    @Override
    public R userReg(LoginFrom loginFrom) {

        //校验验证码
        String mobileKey = loginFrom.getMobile();
        String code = redisTemplate.opsForValue().get(mobileKey);
        if (StringUtils.isEmpty(code)) {
            return R.ERROR(500, "验证码失效");
        }

        if (!code.equals(loginFrom.getCode())) {
            return R.ERROR(500, "验证码错误,请重试");
        }

        //加密
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encode = encoder.encode(loginFrom.getPassword());

        User user = new User();
        user.setUserMobile(loginFrom.getMobile());
        user.setUserName(loginFrom.getUsername());
        user.setUserPass(encode);
        user.setCreateTime(new Date());
        user.setCreateBy("系统");

        //注册
        userMapper.insert(user);

        return R.OK();
    }

    @Override
    public R userLogin(LoginVo loginVo) {
        //用户是否存在
        User userDb = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserMobile, loginVo.getMobile())
        );
        if (ObjectUtil.isEmpty(userDb)) {
            return R.ERROR(500, "用户不存在");
        }

        //校验密码
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean b = passwordEncoder.matches(loginVo.getPassword(), userDb.getUserPass());
        if (!b) {
            return R.ERROR(500, "密码错误");
        }

        //查询角色
        List<String> roleNames = roleMapper.getRoleByUserId(userDb.getUserId());
        StringBuilder stringBuilder = new StringBuilder();
        for (String roleName : roleNames) {
            if (stringBuilder.length() > 0) {
                stringBuilder.append(",").append(roleName);
            } else {
                stringBuilder.append(roleName);
            }
        }

        //生成token
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "bwie")
                .claim("id", userDb.getUserId())
                .claim("userName", userDb.getUserName())
                .compact();
        String tokenKey = "token-" + userDb.getUserId();

        //token存入缓存
        redisTemplate.opsForValue().set(tokenKey, token, 60, TimeUnit.MINUTES);

        userDb.setRoleName(stringBuilder.toString());
        userDb.setToken(token);
        userDb.setUserPass(null);

        //返回
        return R.OK(userDb);
    }

    @Override
    public R getShopUser(PageInfoVo pageInfoVo) {
        Page<User> userPage = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        Page<User> page = userMapper.getShopUser(userPage, pageInfoVo);
        return R.OK(page);
    }
}
